/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.engine.cmd.vfs;

import cn.easyplatform.i18n.I18N;
import cn.easyplatform.interceptor.AbstractCommand;
import cn.easyplatform.interceptor.CommandContext;
import cn.easyplatform.messages.request.vfs.DirRequestMessage;
import cn.easyplatform.messages.response.SimpleResponseMessage;
import cn.easyplatform.messages.vos.VfsVo;
import cn.easyplatform.type.IResponseMessage;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class DirCmd extends AbstractCommand<DirRequestMessage> {

    private final static Logger log = LoggerFactory.getLogger(DirCmd.class);

    /**
     * @param req
     */
    public DirCmd(DirRequestMessage req) {
        super(req);
    }

    @Override
    public IResponseMessage<?> execute(CommandContext cc) {
        String fn = req.getBody();
        try {
            if (fn.startsWith("$7")) {
                fn = cc.getRealPath(fn);
                File folder = new File(fn);
                if (!folder.exists()) {
                    if (!req.isForceMkdir())
                        return new SimpleResponseMessage("e026", I18N.getLabel("vfs.dir.not.found", FilenameUtils.getName(fn)));
                    FileUtils.forceMkdir(folder);
                    return new SimpleResponseMessage(new VfsVo[]{});
                } else if (!folder.isDirectory())
                    return new SimpleResponseMessage("e026", I18N.getLabel("vfs.dir.invalid", FilenameUtils.getName(fn)));
                File[] files = folder.listFiles();
                if (files != null) {
                    List<VfsVo> result = new ArrayList<>(files.length);
                    for (File file : files) {
                        VfsVo fv = new VfsVo();
                        fv.setName(file.getName());
                        fv.setPath(req.getBody() + "/" + file.getName());
                        fv.setModified(file.lastModified());
                        if (file.isFile())
                            fv.setSize(file.length());
                        fv.setFolder(file.isDirectory());
                        result.add(fv);
                    }
                    VfsVo[] vfs = new VfsVo[result.size()];
                    return new SimpleResponseMessage(result.toArray(vfs));
                } else
                    return new SimpleResponseMessage(new VfsVo[]{});
            } else {
                File dir = new File(req.getBody());
                if (!dir.exists()) {
                    if (!req.isForceMkdir())
                        return new SimpleResponseMessage("e026", I18N.getLabel("vfs.dir.not.found", FilenameUtils.getName(fn)));
                    dir.mkdir();
                    return new SimpleResponseMessage(new VfsVo[]{});
                }
                File[] files = dir.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File f) {
                        return !f.isHidden() && !f.getName().startsWith(".");
                    }
                });
                List<VfsVo> result = new ArrayList<>(files.length);
                if (files != null) {
                    for (File file : files) {
                        VfsVo fv = new VfsVo();
                        fv.setName(file.getName());
                        fv.setPath(file.getCanonicalPath());
                        fv.setModified(file.lastModified());
                        if (file.isFile()) {
                            fv.setSize(FileUtils.sizeOf(file));
                        } else
                            fv.setSize(FileUtils.sizeOfDirectory(file));
                        fv.setFolder(file.isDirectory());
                        result.add(fv);
                    }
                }
                Collections.sort(result, new Comparator<VfsVo>() {
                    @Override
                    public int compare(VfsVo o1, VfsVo o2) {
                        return Boolean.valueOf(o1.isFolder()).compareTo(Boolean.valueOf(o2.isFolder()));
                    }
                });
                VfsVo[] vfs = new VfsVo[result.size()];
                return new SimpleResponseMessage(result.toArray(vfs));
            }
        } catch (Exception e) {
            if (log.isErrorEnabled())
                log.error("dir", e);
            return new SimpleResponseMessage("e027", I18N.getLabel("vfs.access.error", e.getMessage()));
        }
    }

}
